Mybatis一二级缓存的实验验证

您所在的位置:网站首页 mybatis 的一二级缓存 Mybatis一二级缓存的实验验证

Mybatis一二级缓存的实验验证

2023-09-24 00:37| 来源: 网络整理| 查看: 265

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 18 天,点击查看活动详情

Mybatis提供了一级缓存和二级缓存,本文介绍如何去了解这两个缓存的概念,具体使用不做评论。

一级缓存:针对的是SqlSession,当SqlSession没有关闭时,该会话中相同的操作会被缓存。 二级缓存:针对的是命名空间,需要手动声明开启二级缓存,二级缓存是当SqlSession关闭后,会将一级缓存的内容放置到二级缓存中。 一级缓存是默认开启的

我们先看配置文件中的一个标签:

在Mybatis配置文件中的标签中有这样一个name子标签localCacheScope,它说明了一级缓存默认是针对Session的:

子标签名称描述取值默认localCacheScopeMyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。 默认值为 SESSION,会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。SESSION / STATEMENTSESSION 实验 这个setting我们不配置,采用Mybatis默认的即可 我们通过sqlSessionFactory获得两个不同的sqlSession 通过sqlSession连续操作两次同样的操作,去判断其值是否相同 // 获得两个不同的Session SqlSession sqlSession = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class); DepartmentMapper departmentMapper2 = sqlSession2.getMapper(DepartmentMapper.class); Department department = departmentMapper.findById("18ec781fbefd727923b0d35740b177ab"); Department department2 = departmentMapper.findById("18ec781fbefd727923b0d35740b177ab"); System.out.println("department == department2 : " + (department == department2)); Department department3 = departmentMapper2.findById("18ec781fbefd727923b0d35740b177ab"); Department department4 = departmentMapper2.findById("18ec781fbefd727923b0d35740b177ab"); System.out.println("department3 == department4 : " + (department3 == department4));

输出结果如下,如果我们使用LOG模式打印的话,也可以看到两个sqlSession做的不同的findByID操作仅仅发送给给了两次sql,表示一级默认缓存是起作用的:

department == department2 : true department3 == department4 : true 二级缓存的开启

默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。要启用全局的二级缓存,很简单,只需要在对应的映射mapper文件中声明标签。

但是请注意两个点:

缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。 二级缓存(命名空间的缓存)是由一级缓存提供的,这个提供动作是sqlSession.close()。 SqlSession sqlSession = sqlSessionFactory.openSession(); SqlSession sqlSession2 = sqlSessionFactory.openSession(); DepartmentMapper departmentMapper = sqlSession.getMapper(DepartmentMapper.class); DepartmentMapper departmentMapper2 = sqlSession2.getMapper(DepartmentMapper.class); Department department = departmentMapper.findById("18ec781fbefd727923b0d35740b177ab"); Department department2 = departmentMapper.findById("18ec781fbefd727923b0d35740b177ab"); System.out.println("department == department2 : " + (department == department2)); sqlSession.close(); // 注意这里!! Department department3 = departmentMapper2.findById("18ec781fbefd727923b0d35740b177ab"); Department department4 = departmentMapper2.findById("18ec781fbefd727923b0d35740b177ab"); System.out.println("department3 == department4 : " + (department3 == department4));

注意看我们添加的sqlSession.close(); 它将sqlSession的一级缓存推送到了二级缓存,那么如果我在命名空间DepartmentMapper.xml中执行的操作,都会在中被保存下来,由于department和department2使用的是一级缓存,所以它们还是相等的。而department3和department4使用的是二级缓存得到的结果,所以它们并不相等,还记得我们说的第一个注意点吗,回去看看。二级缓存的效果就是,它也不会发送sql语句,能直接命中结果。

输出结果如下:

department == department2 : true department3 == department4 : false


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3